from PySide6.QtCore import QObject, Signal
from loguru import logger
from typing import Dict, Optional
from ..models.options_volatility_model import OptionsVolatilityModel
from util import get_previous_trading_date


class OptionsVolatilityController(QObject):
    
    # 波动率偏斜相关信号 - 已注释
    # data_loaded = Signal(dict)  # skew_data
    # loading_state_changed = Signal(bool)  # is_loading
    cone_data_loaded = Signal(dict)  # cone_data (current day only)
    cone_data_with_previous_loaded = Signal(dict)  # combined cone data (current + previous)
    historical_iv_data_loaded = Signal(dict)  # historical_iv_data
    iv_history_data_loaded = Signal(list)  # iv_history_data
    iv_surface_data_loaded = Signal(list)  # iv_surface_data
    historical_iv_loading_state_changed = Signal(bool)  # is_loading
    iv_history_loading_state_changed = Signal(bool)  # is_loading
    iv_surface_loading_state_changed = Signal(bool)  # is_loading
    
    def __init__(self):
        super().__init__()
        self.model = OptionsVolatilityModel()

    def get_underlying_symbols(self):
        return self.model.get_underlying_symbols()

    def get_default_date(self):
        return self.model.get_default_date()

    # 波动率偏斜查询方法 - 已注释
    # def query_options_skew(self, underlying_symbol: str, target_date: str):
    #     if not underlying_symbol:
    #         logger.warning("请选择标的合约")
    #         return
    #         
    #     logger.info(f"开始查询期权skew数据，标的: {underlying_symbol}, 日期: {target_date}")
    #     
    #     self.loading_state_changed.emit(True)
    #     
    #     try:
    #         skew_data = self.model.get_options_skew_data(underlying_symbol, target_date)
    #         
    #         if skew_data:
    #             logger.info(f"获取到期权波动率偏斜数据: {len(skew_data)} 个到期日")
    #             logger.debug(f"数据结构: {list(skew_data.keys()) if isinstance(skew_data, dict) else type(skew_data)}")
    #             self.data_loaded.emit(skew_data)
    #             logger.info("成功加载期权波动率偏斜数据")
    #         else:
    #             logger.warning("未获取到期权波动率偏斜数据")
    #             self.data_loaded.emit({})
    #             
    #     except Exception as e:
    #         logger.exception(f"查询期权skew数据时出错: {e}")
    #         self.data_loaded.emit({})
    #     finally:
    #         self.loading_state_changed.emit(False)

    def query_options_cone(self, underlying_symbol: str, target_date: str):
        """查询期权波动率锥数据（包含当前日期和前一交易日）"""
        if not underlying_symbol:
            logger.warning("请选择标的合约")
            return
            
        logger.info(f"开始查询期权锥数据，标的: {underlying_symbol}, 日期: {target_date}")
        
        try:
            # 查询当前日期的锥数据
            current_cone_data = self.model.get_options_cone_data(underlying_symbol, target_date)
            
            # 获取前一个交易日
            previous_date = get_previous_trading_date(target_date)
            previous_cone_data = None
            
            if previous_date:
                logger.info(f"查询前一交易日锥数据，日期: {previous_date}")
                previous_cone_data = self.model.get_options_cone_data(underlying_symbol, previous_date)
            else:
                logger.warning("无法获取前一交易日，跳过前一日锥数据查询")
            
            # 组合数据
            combined_data = {
                'current': {
                    'date': target_date,
                    'data': current_cone_data if current_cone_data else {}
                },
                'previous': {
                    'date': previous_date,
                    'data': previous_cone_data if previous_cone_data else {}
                }
            }
            
            # 发送组合数据
            self.cone_data_with_previous_loaded.emit(combined_data)
            logger.info("成功加载期权波动率锥数据（含前一交易日）")
                
        except Exception as e:
            logger.exception(f"查询期权锥数据时出错: {e}")
            self.cone_data_with_previous_loaded.emit({
                'current': {'date': target_date, 'data': {}},
                'previous': {'date': None, 'data': {}}
            })

    def query_historical_iv(self, underlying_symbol: str, start_date: str, end_date: str, option_class: str):
        if not underlying_symbol:
            logger.warning("请选择标的合约")
            return
            
        logger.info(f"开始查询历史IV数据，标的: {underlying_symbol}, 日期范围: {start_date} - {end_date}, 期权类型: {option_class}")
        
        self.historical_iv_loading_state_changed.emit(True)
        
        try:
            historical_data = self.model.get_options_atm_historical_iv(underlying_symbol, start_date, end_date, option_class)
            
            if historical_data:
                logger.info(f"获取到历史IV数据: {len(historical_data)} 个到期日")
                self.historical_iv_data_loaded.emit(historical_data)
                logger.info("成功加载历史IV数据")
            else:
                logger.warning("未获取到历史IV数据")
                self.historical_iv_data_loaded.emit({})
                
        except Exception as e:
            logger.exception(f"查询历史IV数据时出错: {e}")
            self.historical_iv_data_loaded.emit({})
        finally:
            self.historical_iv_loading_state_changed.emit(False)

    def query_iv_history(self, underlying_symbol: str, start_date: str, end_date: str):
        """查询IV历史数据"""
        if not underlying_symbol:
            logger.warning("请选择标的合约")
            return
            
        logger.info(f"开始查询IV历史数据，标的: {underlying_symbol}, 日期范围: {start_date} - {end_date}")
        
        self.iv_history_loading_state_changed.emit(True)
        
        try:
            iv_history_data = self.model.get_iv_history(underlying_symbol, start_date, end_date)
            
            if iv_history_data:
                logger.info(f"获取到IV历史数据: {len(iv_history_data)} 条记录")
                self.iv_history_data_loaded.emit(iv_history_data)
                logger.info("成功加载IV历史数据")
            else:
                logger.warning("未获取到IV历史数据")
                self.iv_history_data_loaded.emit([])
                
        except Exception as e:
            logger.exception(f"查询IV历史数据时出错: {e}")
            self.iv_history_data_loaded.emit([])
        finally:
            self.iv_history_loading_state_changed.emit(False)

    def query_iv_surface(self, underlying_symbol: str, date: str, option_class: str):
        """查询期权隐含波动率3D曲面数据"""
        if not underlying_symbol:
            logger.warning("请选择标的合约")
            return
            
        logger.info(f"开始查询3D波动率曲面数据，标的: {underlying_symbol}, 日期: {date}, 期权类型: {option_class}")
        
        self.iv_surface_loading_state_changed.emit(True)
        
        try:
            surface_data = self.model.get_options_iv_surface_data(underlying_symbol, date, option_class)
            
            if surface_data:
                logger.info(f"获取到3D波动率曲面数据: {len(surface_data)} 条记录")
                self.iv_surface_data_loaded.emit(surface_data)
                logger.info("成功加载3D波动率曲面数据")
            else:
                logger.warning("未获取到3D波动率曲面数据")
                self.iv_surface_data_loaded.emit([])
                
        except Exception as e:
            logger.exception(f"查询3D波动率曲面数据时出错: {e}")
            self.iv_surface_data_loaded.emit([])
        finally:
            self.iv_surface_loading_state_changed.emit(False)